#include "motor_pwm.h"

#include "stm32f1xx_hal.h"

MotorPWMChannelConfigType g_pwm_channels[MOTOR_PWM_Chan_MAX];


static TIM_HandleTypeDef* get_timer_from_channels(MotorPWMChannelConfigType g_pwm_channels[MOTOR_PWM_Chan_MAX]);


void motor_pwm_init(void)
{
    // 初始化已完成，由STM32CubeMX生成
    // 这里可以添加额外的初始化代码

	for (int i = 0; i < MOTOR_PWM_Chan_MAX; i++) {
        g_pwm_channels[i].htim = NULL;
        g_pwm_channels[i].channel = 0;
        g_pwm_channels[i].gpio = NULL;
        g_pwm_channels[i].pin = 0;
        g_pwm_channels[i].channel_type = i;
    }
}


void motor_pwm_set_channel(MotorPWMChannelConfigType g_pwm_channels[], 
                          MotorPWMChannelType_e channel_type,
                          TIM_HandleTypeDef *htim,
                          uint32_t channel,
                          GPIO_TypeDef *port,
                          uint16_t pin)
{
    if (channel_type >= MOTOR_PWM_Chan_MAX) return;
    
    g_pwm_channels[channel_type].htim = htim;
    g_pwm_channels[channel_type].channel = channel;
    g_pwm_channels[channel_type].gpio = port;
    g_pwm_channels[channel_type].pin = pin;
    g_pwm_channels[channel_type].channel_type = channel_type;
}

void motor_pwm_freq_set(MotorPWMChannelConfigType g_pwm_channels[MOTOR_PWM_Chan_MAX],
                       uint16_t freqBase, uint16_t dead_time)
{
    TIM_HandleTypeDef* pwm_tim = get_timer_from_channels(g_pwm_channels);
    if (pwm_tim == NULL) return;
    
    // 停止PWM输出 before reconfiguration
    motor_pwm_stop();
    
    // 计算ARR值
    uint32_t timer_clock = HAL_RCC_GetPCLK2Freq();
	if(freqBase > 0)
	{
		uint32_t arr_value = (timer_clock / freqBase) - 1;
		
		// 更新定时器参数
		__HAL_TIM_SET_AUTORELOAD(pwm_tim, arr_value);
	}
    
    // 设置死区时间
    if (dead_time > 0) {
        uint32_t dead_time_count = (dead_time * timer_clock) / 1000000;
        // 确保死区时间在有效范围内
        dead_time_count = (dead_time_count > 0xFF) ? 0xFF : dead_time_count;
        __HAL_TIM_SET_DEADTIME(pwm_tim, dead_time_count);
    }
    
    // 重新初始化定时器
    HAL_TIM_PWM_Init(pwm_tim);
}

void motor_pwm_set_duty(MotorPWMChannelConfigType g_pwm_channels[MOTOR_PWM_Chan_MAX],
                       MotorPWMChannelType_e channel_type, uint16_t duty)
{
    if (channel_type >= MOTOR_PWM_Chan_MAX) return;
    if (g_pwm_channels[channel_type].htim == NULL) return;
    
    // 限制占空比在有效范围内
    if (duty > PWM_Duty_Max) duty = PWM_Duty_Max;
    
    // 获取ARR值
    uint32_t arr_value = __HAL_TIM_GET_AUTORELOAD(g_pwm_channels[channel_type].htim);
    
    // 计算比较值
    uint32_t compare_value = (duty * arr_value) / PWM_Duty_Max;
    
    // 设置通道比较值
    __HAL_TIM_SET_COMPARE(g_pwm_channels[channel_type].htim, 
                         g_pwm_channels[channel_type].channel, 
                         compare_value);
}

void motor_pwm_set_duties_advanced(MotorPWMChannelConfigType g_pwm_channels[MOTOR_PWM_Chan_MAX],
                                  uint16_t duty_a, uint16_t duty_b, uint16_t duty_c)
{
    // 限制占空比在有效范围内
    if (duty_a > PWM_Duty_Max) duty_a = PWM_Duty_Max;
    if (duty_b > PWM_Duty_Max) duty_b = PWM_Duty_Max;
    if (duty_c > PWM_Duty_Max) duty_c = PWM_Duty_Max;
    
    // 获取ARR值（假设所有通道使用同一个定时器）
    TIM_HandleTypeDef* pwm_tim = NULL;
    for (int i = 0; i < MOTOR_PWM_Chan_MAX; i++) {
        if (g_pwm_channels[i].htim != NULL) {
            pwm_tim = g_pwm_channels[i].htim;
            break;
        }
    }
    
    if (pwm_tim == NULL) return;
    
    uint32_t arr_value = __HAL_TIM_GET_AUTORELOAD(pwm_tim);
    
    // 计算比较值
    uint32_t compare_a = (duty_a * arr_value) / PWM_Duty_Max;
    uint32_t compare_b = (duty_b * arr_value) / PWM_Duty_Max;
    uint32_t compare_c = (duty_c * arr_value) / PWM_Duty_Max;
    
    // 设置各通道比较值
    for (int i = 0; i < MOTOR_PWM_Chan_MAX; i++) {
        if (g_pwm_channels[i].htim == NULL) continue;
        
        switch (g_pwm_channels[i].channel_type) {
            case MOTOR_PWM_Chan_U_H:
                __HAL_TIM_SET_COMPARE(g_pwm_channels[i].htim, g_pwm_channels[i].channel, compare_a);
                break;
            case MOTOR_PWM_Chan_V_H:
                __HAL_TIM_SET_COMPARE(g_pwm_channels[i].htim, g_pwm_channels[i].channel, compare_b);
                break;
            case MOTOR_PWM_Chan_W_H:
                __HAL_TIM_SET_COMPARE(g_pwm_channels[i].htim, g_pwm_channels[i].channel, compare_c);
                break;
            // 低侧通道通常与高侧通道互补，由硬件自动控制
            default:
                break;
        }
    }
}

void motor_pwm_start(void)
{
    for (int i = 0; i < MOTOR_PWM_Chan_MAX; i++) {
        if (g_pwm_channels[i].htim == NULL) continue;
        
        HAL_TIM_PWM_Start(g_pwm_channels[i].htim, g_pwm_channels[i].channel);
        
        // 如果是高侧通道，启动互补通道
        if (g_pwm_channels[i].channel_type <= MOTOR_PWM_Chan_W_H) {
            HAL_TIMEx_PWMN_Start(g_pwm_channels[i].htim, g_pwm_channels[i].channel);
        }
    }
}

void motor_pwm_stop(void)
{
    for (int i = 0; i < MOTOR_PWM_Chan_MAX; i++) {
        if (g_pwm_channels[i].htim == NULL) continue;
        
        HAL_TIM_PWM_Stop(g_pwm_channels[i].htim, g_pwm_channels[i].channel);
        
        // 停止互补通道
        if (g_pwm_channels[i].channel_type <= MOTOR_PWM_Chan_W_H) {
            HAL_TIMEx_PWMN_Stop(g_pwm_channels[i].htim, g_pwm_channels[i].channel);
        }
    }
    
    // 将所有占空比设置为0
    motor_pwm_set_duties(g_pwm_channels, 0, 0, 0);
}

// 内部函数：从通道配置中获取定时器
static TIM_HandleTypeDef* get_timer_from_channels(MotorPWMChannelConfigType g_pwm_channels[MOTOR_PWM_Chan_MAX])
{
    for (int i = 0; i < MOTOR_PWM_Chan_MAX; i++) {
        if (g_pwm_channels[i].htim != NULL) {
            return g_pwm_channels[i].htim;
        }
    }
    return NULL;
}


//void motor_pwm_start(void)
//{
//    // 启动PWM输出
//	for(int i = 0; i < MOTOR_PWM_Chan_MAX; i++)
//	{
//		if(g_pwm_channels[i].htim != NULL)
//		{
//			HAL_TIM_PWM_Start(g_pwm_channels[i].htim, g_pwm_channels[i].channel);
//			// 启动互补通道和刹车功能（如果需要）
//			HAL_TIMEx_PWMN_Start(g_pwm_channels[i].htim, g_pwm_channels[i].channel)
//		}
//	}
//}

//void motor_pwm_stop(void)
//{
//    // 停止PWM输出
//	for(int i = 0; i < MOTOR_PWM_Chan_MAX; i++)
//	{
//		if(g_pwm_channels[i].htim != NULL)
//		{
//			HAL_TIM_PWM_Stop(g_pwm_channels[i].htim, g_pwm_channels[i].channel);
//			// 启动互补通道和刹车功能（如果需要）
//			HAL_TIMEx_PWMN_Stop(g_pwm_channels[i].htim, g_pwm_channels[i].channel)
//		}
//	}
//    // 将所有占空比设置为0
//    motor_pwm_set_duties(0, 0, 0);
//}

void motor_pwm_set_foc_outputs(MotorPWMChannelConfigType g_pwm_channels[MOTOR_PWM_Chan_MAX],
                              const FOCOutputs* foc_outputs)
{
    if (foc_outputs == NULL) {
        return;
    }
    
    // 将FOC输出的三相PWM值(-FIXED_SCALE到FIXED_SCALE)转换为占空比(0-PWM_Duty_Max)
    // 转换公式: duty = (value + FIXED_SCALE) * PWM_Duty_Max / (2 * FIXED_SCALE)
    
    uint16_t duty_a = (int32_t)(foc_outputs->DC_phaA + FIXED_SCALE) * PWM_Duty_Max / (2 * FIXED_SCALE);
    uint16_t duty_b = (int32_t)(foc_outputs->DC_phaB + FIXED_SCALE) * PWM_Duty_Max / (2 * FIXED_SCALE);
    uint16_t duty_c = (int32_t)(foc_outputs->DC_phaC + FIXED_SCALE) * PWM_Duty_Max / (2 * FIXED_SCALE);
    
    // 确保占空比在有效范围内
    duty_a = (duty_a > PWM_Duty_Max) ? PWM_Duty_Max : duty_a;
    duty_b = (duty_b > PWM_Duty_Max) ? PWM_Duty_Max : duty_b;
    duty_c = (duty_c > PWM_Duty_Max) ? PWM_Duty_Max : duty_c;
    
    // 设置三相PWM占空比
    motor_pwm_set_duties_advanced(g_pwm_channels, duty_a, duty_b, duty_c);
}

